#include <stdio.h>
#include <dlfcn.h>
#include <string.h>
#include "ipmi_netfn.h"

static table_netfn_t table_netfn[] = {
    { NETFN_0x00, 0 }, //0x00/01
    { NETFN_0x02, 0 }, //0x02/03
    { NETFN_0x04, 0 }, //0x04/05
    { NETFN_0x06, 0 }, //0x06/07
    { NETFN_0x08, 0 }, //0x08/09
    { NETFN_0x0A, 0 }, //0x0A/0B
    { NETFN_0x0C, 0 }, //0x0C/0D
    { NETFN_0x2C, 0 }, //0x2C/2D
    { NETFN_0x2E, 0 }, //0x2E/2F
    { NETFN_0x30, 0 }, //0x30/31
    { NETFN_0x32, 0 }, //0x32/33
    { NETFN_0x34, 0 }, //0x34/35
    { NETFN_0x36, 0 }, //0x36/37
    { NETFN_0x38, 0 }, //0x38/39
    { NETFN_0x3A, 0 }, //0x3A/3B
    { NETFN_0x3C, 0 }, //0x3C/3D
    { NETFN_0x3E, 0 }, //0x3E/3F
};

void get_command(uint8 netfn, uint8 cmd, uint8* pcmd)
{
    int i = 0;
    cmd_assigments_t* ptr_cmd = (cmd_assigments_t*)pcmd;
    pcmd = NULL;
    for(i=0; i<ARRAY_SIZEOF(table_netfn); i++){
        if(table_netfn[i].netfn == netfn){
            if(table_netfn[i].cmds[cmd].enable){
                memcpy(ptr_cmd, &table_netfn[i].cmds[cmd].cmd_assigments, sizeof(cmd_assigments_t));
            }else{
                ptr_cmd->command_entrance = NULL;
            }
            return;
        }
    }
}

void show_command_info()
{
    int i = 0;
    int j = 0;
    for(i=0; i<ARRAY_SIZEOF(table_netfn); i++){
        for(j=0; j<COMMAND_NUMBERS; j++){
            if(table_netfn[i].cmds[j].enable){
                printf("[%x,%x]:Ch:%x,Pri:%x\n",i,j,table_netfn[i].cmds[j].cmd_assigments.channel, table_netfn[i].cmds[j].cmd_assigments.privilege);
            }
        }
    }
}

int8 enable_command(uint8 netfn, uint8 cmd)
{
    uint8 so_name[255]="";
    uint8 netfn_index = 0;
    uint8 i = 0;
    for(i=0; i<ARRAY_SIZEOF(table_netfn); i++){
        if(table_netfn[i].netfn == netfn)
            netfn_index = i;
    }
    table_cmd_t* pcmd = &table_netfn[netfn_index].cmds[cmd];
    if(pcmd->enable){
        printf("already enable command [0x%02x, 0x%02x].\n", netfn, cmd);
        return FALSE;
    }
    sprintf(so_name, LIBRARY_PATH, netfn, cmd);
    pcmd->enable = dlopen(so_name, RTLD_LAZY);
    if(!pcmd->enable){
//        printf("cannot found library:%s!!\n",so_name);
        return FALSE;
    }
    pcmd->init_command = (init_command_f)dlsym(pcmd->enable, "init_command");
    if(!pcmd->init_command){
        dlclose(pcmd->enable);
        printf("cannot found function:init_command()!!\n");
        return FALSE;
    }
    printf("found library:%s!!\n",so_name);
    pcmd->init_command(&pcmd->cmd_assigments);
    return TRUE;
}

int8 disable_command(uint8 netfn, uint8 cmd)
{
    table_cmd_t* pcmd = &table_netfn[netfn].cmds[cmd];
    if(!pcmd->enable){
        printf("already disable command [0x%02x, 0x%02x].\n", netfn, cmd);
        return TRUE;
    }
    dlclose(pcmd->enable);
    return TRUE;
}

void init_command()
{
    int netfn = 0;
    int i = 0;
    int cmd = 0;
    for(i=0; i<ARRAY_SIZEOF(table_netfn); i++){
            netfn = table_netfn[i].netfn;
        for(cmd=0; cmd<COMMAND_NUMBERS; cmd++){
            enable_command(netfn, cmd);
        }
    }
}
